#include <48func.h>
typedef struct clientInfo_s {
    int isalive;
    int netfd;
    time_t lastactive;
} clientInfo_t;
int main(int argc, char *argv[])
{
    // ./1_server 192.168.118.128 1234
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//ipv4 tcp
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    int reuseArg = 1;
    int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuseArg,sizeof(reuseArg));
    ERROR_CHECK(ret,-1,"setsockopt");
    ret = bind(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"bind");
    ret = listen(sockfd,10);
    ERROR_CHECK(ret,-1,"listen");
    char buf[4096];
    // 准备好监听集合
    fd_set monitorset;
    FD_ZERO(&monitorset);
    // 把sockfd加入监听
    FD_SET(sockfd,&monitorset);
    // 准备好数据结构 存储客户端的信息
    clientInfo_t client[1024];
    int curidx = 0;
    while(1){
        fd_set rdset;
        memcpy(&rdset,&monitorset,sizeof(fd_set));
        struct timeval timeout;
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        select(1024,&rdset,NULL,NULL,&timeout);//rdset会被修改
        time_t curtime = time(NULL);
        printf("curtime = %s\n", ctime(&curtime));
        if(FD_ISSET(sockfd,&rdset)){
            struct sockaddr_in clientAddr;
            socklen_t socklen = sizeof(clientAddr);//socklen必须初始化
            client[curidx].netfd = accept(sockfd,(struct sockaddr *)&clientAddr,&socklen);
            ERROR_CHECK(client[curidx].netfd,-1,"accept");
            printf("client ip = %s, port = %d\n",
                   inet_ntoa(clientAddr.sin_addr),
                   ntohs(clientAddr.sin_port));
            // 增加netfd
            client[curidx].isalive = 1; // 该客户端目前已经连接
            FD_SET(client[curidx].netfd,&monitorset);
            // 记录活跃时间
            client[curidx].lastactive = time(NULL);
            ++curidx;
        }
        for(int i = 0; i < curidx; ++i){
            if(client[i].isalive != 0 && FD_ISSET(client[i].netfd,&rdset)){
                //广播
                client[i].lastactive = time(NULL); // 记录活跃时间
                bzero(buf,sizeof(buf));
                ssize_t sret = recv(client[i].netfd,buf,sizeof(buf),0);
                if(sret == 0){
                    FD_CLR(client[i].netfd,&monitorset);
                    close(client[i].netfd);
                    client[i].isalive = 0;
                    break;
                }
                for(int j = 0; j < curidx; ++j){
                    if(j == i){
                        continue;
                    }
                    if(client[j].isalive != 0){
                        sret = send(client[j].netfd,buf,strlen(buf),0);
                        ERROR_CHECK(sret,-1,"send");
                    }
                }
            }
        }
        for(int i = 0; i < curidx; ++i){
            if(client[i].isalive == 0){
                continue;
            }
            if(curtime - client[i].lastactive > 5){
                printf("close %d client!\n", i);
                FD_CLR(client[i].netfd,&monitorset);
                close(client[i].netfd);
                client[i].isalive = 0;
            }
        }
    }
    return 0;
}



